package whf.framework.report.export.view;

import java.util.Map;

import whf.framework.config.ApplicationConfig;
import whf.framework.report.export.util.ExportUtils;
import whf.framework.util.StringUtils;
import whf.framework.web.tag.TableModel;
import whf.framework.web.tag.ext.IColumn;

/**
 * @author wanghaifeng
 *
 */
public class AppletView extends AbstractView {
	private final static int DEFAULT_HEADER_HEIGHT = 35;

	private String headerTitle;

	private String reportName;

	private int reportWidth = 535;

	private StringBuffer jasper = new StringBuffer();

	public AppletView(TableModel tableModel, Map<String, String> params) {
		super(null, tableModel);
		this.headerTitle = params.get(ExportUtils.EXPORT_HEADER_TITLE);
		this.reportName = params.get(ExportUtils.REPORT_NAME);
		if(StringUtils.isEmpty(headerTitle)){
			this.headerTitle = super.getHeaderTitle();
		}
	}

	public void beforeBody() {
		jasper.append(parseRoot());
		jasper.append(parseQueryDefine());
		jasper.append(parseBackGround());
		jasper.append(parseTitle());
		jasper.append(parsePageheader());
		jasper.append(parseColumnHeader());
	}

	public int getHeaderHeight() {
		int columnCount = this.columns.size() == 0 ? 1 : this.columns.size() + 1;
		int perColumnWidth = this.reportWidth / columnCount;
		String maxLengthHeader = "";
		for(IColumn col : this.columns){
			String header = col.getDisplayTitle();
			if (!StringUtils.isEmpty(header) && header.length() > maxLengthHeader.length()) {
				maxLengthHeader = header;
			}
		}
		int requiredHeaderWidth = maxLengthHeader.length() * 4;
		int headerHeight = DEFAULT_HEADER_HEIGHT;
		int lineCount = requiredHeaderWidth / perColumnWidth;
		for (int i = 0; i < lineCount; i++) {
			headerHeight += 15;
		}
		return headerHeight;
	}

	public void doBody() {
		String firstColBox = "<box topBorder=\"None\" topBorderColor=\"#000000\""
				+ " leftBorder=\"Thin\" leftBorderColor=\"#000000\""
				+ " rightBorder=\"Thin\" rightBorderColor=\"#000000\""
				+ " bottomBorder=\"Thin\" bottomBorderColor=\"#000000\"/>";

		String otherColBox = "<box topBorder=\"None\" topBorderColor=\"#000000\""
				+ " leftBorder=\"None\" leftBorderColor=\"#000000\""
				+ " rightBorder=\"Thin\" rightBorderColor=\"#000000\""
				+ " bottomBorder=\"Thin\" bottomBorderColor=\"#000000\"/>";
		jasper.append("<detail>").append(
				"<band height=\"32\"  isSplitAllowed=\"true\" >");
		
		int size = this.columns.size();
		int colWidth = reportWidth / size;

		for (int i = 0; i < size; i++) {
			int start = i * colWidth;
			IColumn col = this.columns.get(i);
			
			jasper.append("<textField isStretchWithOverflow=\"true\""
							+ " pattern=\"\" isBlankWhenNull=\"true\" evaluationTime=\"Now\""
							+ " hyperlinkType=\"None\"  hyperlinkTarget=\"Self\" >");
			jasper.append("<reportElement mode=\"Transparent\" x=\"")
					.append(start).append("\" y=\"0\" width=\"").append(colWidth)
					.append("\"").append(" height=\"32\" forecolor=\"#000000\" backcolor=\"#FFFFFF\" key=\"textField\" stretchType=\"RelativeToTallestObject\" ")
					.append(" isPrintRepeatedValues=\"true\" isRemoveLineWhenBlank=\"false\" isPrintInFirstWholeBand=\"false\"")
					.append(" isPrintWhenDetailOverflows=\"true\"/>");

			if (i == 0) {
				jasper.append(firstColBox);
			} else {
				jasper.append(otherColBox);
			}

			jasper.append("<textElement textAlignment=\"Center\" verticalAlignment=\"Middle\" rotation=\"None\" lineSpacing=\"Single\">");
			jasper.append("<font reportFont=\"DetailFont\" />");
			jasper.append("</textElement>");
			jasper.append("<textFieldExpression   class=\"java.lang.String\"><![CDATA[$F{")
					.append(col.getProperty()).append("}]]></textFieldExpression>");
			jasper.append("</textField>");
		}
		jasper.append("</band>").append("</detail>");
	}

	public Object afterBody() {
		jasper.append(parseColumnFooter());
		jasper.append(parsePageFooter());
		jasper.append(parseLastPageFooter());
		jasper.append(parseSummary());
		return jasper.toString();
	}

	public String parseRoot() {
		StringBuffer sb = new StringBuffer();
		// handle jasper report define
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"  ?>");
		sb.append("<jasperReport name=\"")
				.append(reportName)
				.append("\"")
				.append(" language=\"java\" columnCount=\"1\" printOrder=\"Vertical\"")
				.append(" orientation=\"Portrait\" pageWidth=\"595\" pageHeight=\"842\"")
				.append(" columnWidth=\"535\" columnSpacing=\"0\" leftMargin=\"30\" rightMargin=\"30\"")
				.append(" topMargin=\"20\" bottomMargin=\"20\" whenNoDataType=\"NoPages\" isTitleNewPage=\"false\"")
				.append(" isSummaryNewPage=\"false\">");
		// handle property
		sb.append("<property name=\"ireport.scriptlethandling\" value=\"0\" />");
		sb.append("<property name=\"ireport.encoding\" value=\"UTF-8\" />");
		// handle import property
		sb.append("<import value=\"java.util.*\" />");
		sb.append("<import value=\"net.sf.jasperreports.engine.*\" />");
		sb.append("<import value=\"net.sf.jasperreports.engine.data.*\" />");
		// handle fonts define
		String font1 = ApplicationConfig.getInstance().getValue(ExportUtils.EXPORT_PDF_TITLE_FONT);
		String font2 = ApplicationConfig.getInstance().getValue(ExportUtils.EXPORT_PDF_BODY_FONT);
		sb.append("<reportFont name=\"TitleFont\" isDefault=\"false\" fontName=\"宋体\" size=\"18\" isBold=\"true\" isItalic=\"false\" isUnderline=\"false\" isStrikeThrough=\"false\"  pdfFontName=\""
						+ font1
						+ "\" pdfEncoding=\"Identity-H\" isPdfEmbedded=\"true\"/>");
		sb.append("<reportFont name=\"HeaderFont\" isDefault=\"false\" fontName=\"宋体\" size=\"10\" isBold=\"true\" isItalic=\"false\" isUnderline=\"false\" isStrikeThrough=\"false\"  pdfFontName=\""
						+ font2
						+ "\" pdfEncoding=\"Identity-H\" isPdfEmbedded=\"true\"/>");
		sb.append("<reportFont name=\"DetailFont\" isDefault=\"false\" fontName=\"宋体\" size=\"9\" isBold=\"false\" isItalic=\"false\" isUnderline=\"false\" isStrikeThrough=\"false\"   pdfFontName=\"STSong-Light\" pdfEncoding=\"UniGB-UCS2-H\" isPdfEmbedded=\"true\"/>");
		return sb.toString();
	}

	public String parseQueryDefine() {
		StringBuffer sb = new StringBuffer();
		for(IColumn col: this.columns){
			sb.append("<field name=\"").append(col.getProperty()).append("\"  class=\"java.lang.String\"/>");
		}
		return sb.toString();
	}

	public String parseBackGround() {
		StringBuffer sb = new StringBuffer();
		sb.append("<background><band height=\"0\"  isSplitAllowed=\"true\" ></band></background>");
		return sb.toString();
	}

	public String parseTitle() {
		StringBuffer sb = new StringBuffer();
		sb.append("<title>");
		sb.append("<band height=\"77\"  isSplitAllowed=\"true\" >");
		sb.append("<staticText>");
		// define reportElement
		sb.append("<reportElement mode=\"Transparent\" x=\"0\"  y=\"0\" width=\"535\" height=\"77\"")
				.append(" forecolor=\"#000000\" backcolor=\"#FFFFFF\" key=\"staticText-1\" stretchType=\"NoStretch\"")
				.append(" positionType=\"FixRelativeToTop\" isPrintRepeatedValues=\"true\" isRemoveLineWhenBlank=\"false\"")
				.append(" isPrintInFirstWholeBand=\"false\" isPrintWhenDetailOverflows=\"false\" />");
		// define box
		sb.append("<box topBorder=\"None\" topBorderColor=\"#000000\" leftBorder=\"None\"")
				.append(" leftBorderColor=\"#000000\" rightBorder=\"None\" rightBorderColor=\"#000000\"")
				.append(" bottomBorder=\"None\" bottomBorderColor=\"#000000\"/>");
		// define text element
		sb.append("<textElement textAlignment=\"Center\" verticalAlignment=\"Middle\" rotation=\"None\" lineSpacing=\"Single\">");
		sb.append(" <font reportFont=\"TitleFont\"/>");
		sb.append("</textElement>");
		// define text
		sb.append("<text><![CDATA[").append(headerTitle).append("]]></text>");
		// end define static text
		sb.append("</staticText>").append("</band>").append("</title>");
		return sb.toString();
	}

	public String parsePageheader() {
		StringBuffer sb = new StringBuffer();
		sb.append("<pageHeader><band height=\"0\"  isSplitAllowed=\"true\" ></band></pageHeader>");
		return sb.toString();
	}

	public String parseColumnHeader() {
		String firstColBox = "<box topBorder=\"Thin\" topBorderColor=\"#000000\" leftBorder=\"Thin\""
				+ " leftBorderColor=\"#000000\" rightBorder=\"Thin\" "
				+ "rightBorderColor=\"#000000\" bottomBorder=\"Thin\""
				+ " bottomBorderColor=\"#000000\"/>";

		String otherColBox = "<box topBorder=\"Thin\" topBorderColor=\"#000000\" leftBorder=\"None\""
				+ " leftBorderColor=\"#000000\" rightBorder=\"Thin\" "
				+ "rightBorderColor=\"#000000\" bottomBorder=\"Thin\""
				+ " bottomBorderColor=\"#000000\"/>";

		StringBuffer sb = new StringBuffer();
		sb.append("<columnHeader><band height=\"" + this.getHeaderHeight() + "\"  isSplitAllowed=\"true\" >");
		
		int size = this.columns.size();
		int colWidth = reportWidth / size;

		for (int i = 0; i < size; i++) {
			IColumn col = this.columns.get(i);
			int start = i * colWidth;
			sb.append("<staticText>");
			sb.append("<reportElement mode=\"Transparent\" x=\"").append(start)
					.append("\" y=\"0\" width=\"").append(colWidth).append("\"")
					.append(" height=\"" + this.getHeaderHeight() + "\" forecolor=\"#000000\" backcolor=\"#FFFFFF\"")
					.append(" key=\"staticHeaderText-").append(i)
					.append("\" stretchType=\"NoStretch\" positionType=\"FixRelativeToTop\"")
					.append(" isPrintRepeatedValues=\"true\" isRemoveLineWhenBlank=\"false\"")
					.append(" isPrintInFirstWholeBand=\"false\" isPrintWhenDetailOverflows=\"false\"/>");

			if (i == 0) {
				sb.append(firstColBox);
			} else {
				sb.append(otherColBox);
			}

			sb.append("<textElement textAlignment=\"Center\" verticalAlignment=\"Middle\""
					+ " rotation=\"None\" lineSpacing=\"Single\">");

			sb.append("<font reportFont=\"HeaderFont\"/>");
			sb.append("</textElement>");
			sb.append("<text><![CDATA[").append(col.getDisplayTitle()).append("]]>").append("</text></staticText>");
		}

		sb.append("	</band></columnHeader>");
		return sb.toString();
	}

	public String parseColumnFooter() {
		StringBuffer sb = new StringBuffer();
		sb.append("<columnFooter><band height=\"0\"  isSplitAllowed=\"true\" ></band></columnFooter>");
		return sb.toString();
	}

	public String parsePageFooter() {
		StringBuffer sb = new StringBuffer();
		sb.append("<pageFooter><band height=\"0\"  isSplitAllowed=\"true\" ></band></pageFooter>");
		return sb.toString();
	}

	public String parseLastPageFooter() {
		StringBuffer sb = new StringBuffer();
		sb.append("<lastPageFooter><band height=\"0\"  isSplitAllowed=\"true\" ></band></lastPageFooter>");
		return sb.toString();
	}

	public String parseSummary() {
		StringBuffer sb = new StringBuffer();
		sb.append("<summary><band height=\"0\"  isSplitAllowed=\"true\" ></band></summary>");
		sb.append("</jasperReport>");
		return sb.toString();
	}

	/**
	 * @return Returns the jasper.
	 */
	public StringBuffer getJasper() {
		return jasper;
	}

	/**
	 * @param jasper
	 *            The jasper to set.
	 */
	public void setJasper(StringBuffer jasper) {
		this.jasper = jasper;
	}

	/**
	 * @return Returns the cOL_TOTAL_WIDTH.
	 */
	public int getReportWidth() {
		return reportWidth;
	}

	/**
	 * @param col_total_width
	 *            The cOL_TOTAL_WIDTH to set.
	 */
	public void setReportWidth(int col_total_width) {
		reportWidth = col_total_width;
	}
}
